home *** CD-ROM | disk | FTP | other *** search
- #include "mesh.h"
-
- const DWORD ObjectVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
-
- MESH::MESH()
- {
- m_pDevice = NULL;
- m_pMesh = NULL;
- m_pProgressiveMesh = NULL;
- }
-
- MESH::MESH(char fName[], IDirect3DDevice9* Dev)
- {
- m_pDevice = Dev;
- m_pMesh = NULL;
- m_pProgressiveMesh = NULL;
- Load(fName, m_pDevice);
- }
-
- MESH::~MESH()
- {
- Release();
- }
-
- HRESULT MESH::Load(char fName[], IDirect3DDevice9* Dev)
- {
- m_pDevice = Dev;
-
- try
- {
- //Set white material
- m_white.Ambient = m_white.Specular = m_white.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
- m_white.Emissive = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
- m_white.Power = 1.0f;
-
- Release();
-
- //Load new mesh
- ID3DXBuffer * adjacencyBfr = NULL;
- ID3DXBuffer * materialBfr = NULL;
- DWORD noMaterials = NULL;
-
- if(FAILED(D3DXLoadMeshFromX(fName, D3DXMESH_MANAGED, m_pDevice, &adjacencyBfr, &materialBfr, NULL, &noMaterials, &m_pMesh)))
- return E_FAIL;
-
- D3DXMATERIAL *mtrls = (D3DXMATERIAL*)materialBfr->GetBufferPointer();
-
- for(int i=0;i<noMaterials;i++)
- {
- m_materials.push_back(mtrls[i].MatD3D);
-
- if(mtrls[i].pTextureFilename != NULL)
- {
- char textureFileName[90];
- strcpy(textureFileName, "objects/");
- strcat(textureFileName, mtrls[i].pTextureFilename);
- IDirect3DTexture9 * newTexture = NULL;
- D3DXCreateTextureFromFile(m_pDevice, textureFileName, &newTexture);
- m_textures.push_back(newTexture);
- }
- else m_textures.push_back(NULL);
- }
-
- //Release buffers
- adjacencyBfr->Release();
- materialBfr->Release();
-
- //Create progressive mesh
- DWORD *adj = new DWORD[m_pMesh->GetNumFaces() * 3];
- m_pMesh->GenerateAdjacency(0.0f, adj); //Load Adjancency Table
-
- if(FAILED(D3DXGeneratePMesh(m_pMesh, adj, NULL, NULL,
- 1, D3DXMESHSIMP_FACE, &m_pProgressiveMesh)))
- {
- debug.Print("Failed to create progressive mesh");
- exit(0);
- }
-
- delete [] adj;
-
- m_pProgressiveMesh->SetNumFaces(m_pMesh->GetNumFaces());
-
-
- }
- catch(...)
- {
- debug.Print("Error in MESH::Load()");
- return E_FAIL;
- }
-
- return S_OK;
- }
-
- void MESH::Render()
- {
- if(m_pMesh != NULL)
- for(int i=0;i<m_materials.size();i++)
- {
- if(m_textures[i] != NULL)m_pDevice->SetMaterial(&m_white);
- else m_pDevice->SetMaterial(&m_materials[i]);
- m_pDevice->SetTexture(0,m_textures[i]);
- m_pMesh->DrawSubset(i);
- }
- }
-
- void MESH::SetLOD(int numFaces)
- {
- if(m_pProgressiveMesh == NULL)return;
- m_pProgressiveMesh->SetNumFaces(numFaces); //Set LOD
- }
-
- void MESH::RenderProgressive()
- {
- if(m_pProgressiveMesh != NULL)
- for(int i=0;i<m_materials.size();i++)
- {
- if(m_textures[i] != NULL)m_pDevice->SetMaterial(&m_white);
- else m_pDevice->SetMaterial(&m_materials[i]);
- m_pDevice->SetTexture(0,m_textures[i]);
- m_pProgressiveMesh->DrawSubset(i);
- }
- }
-
- void MESH::Release()
- {
- //Clear old mesh...
- if(m_pMesh != NULL)
- {
- m_pMesh->Release();
- m_pMesh = NULL;
- }
-
- if(m_pProgressiveMesh != NULL)
- {
- m_pProgressiveMesh->Release();
- m_pProgressiveMesh = NULL;
- }
-
- //Clear textures and materials
- for(int i=0;i<m_textures.size();i++)
- if(m_textures[i] != NULL)
- m_textures[i]->Release();
-
- m_textures.clear();
- m_materials.clear();
- }
-
- MESHINSTANCE::MESHINSTANCE()
- {
- m_pMesh = NULL;
- m_pos = m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
- m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
- }
-
- MESHINSTANCE::MESHINSTANCE(MESH *meshPtr)
- {
- m_pMesh = meshPtr;
- m_pos = m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
- m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
- }
-
- D3DXMATRIX MESHINSTANCE::GetWorldMatrix()
- {
- D3DXMATRIX p, r, s;
- D3DXMatrixTranslation(&p, m_pos.x, m_pos.y, m_pos.z);
- D3DXMatrixRotationYawPitchRoll(&r, m_rot.y, m_rot.x, m_rot.z);
- D3DXMatrixScaling(&s, m_sca.x, m_sca.y, m_sca.z);
-
- D3DXMATRIX world = s * r * p;
- return world;
- }
-
- void MESHINSTANCE::Render()
- {
- if(m_pMesh != NULL)
- {
- m_pMesh->m_pDevice->SetTransform(D3DTS_WORLD, &GetWorldMatrix());
- m_pMesh->Render();
- }
- }
-
- void MESHINSTANCE::SetLOD(int numFaces)
- {
- if(m_pMesh != NULL)
- m_pMesh->SetLOD(numFaces);
- }
-
- void MESHINSTANCE::RenderProgressive()
- {
- if(m_pMesh != NULL)
- {
- m_pMesh->m_pDevice->SetTransform(D3DTS_WORLD, &GetWorldMatrix());
- m_pMesh->RenderProgressive();
- }
- }
-
- BBOX MESHINSTANCE::GetBoundingBox()
- {
- if(m_pMesh == NULL || m_pMesh->m_pMesh == NULL)return BBOX();
-
- if(m_pMesh->m_pMesh->GetFVF() != ObjectVertex::FVF) // XYZ and NORMAL and UV
- return BBOX();
-
- BBOX bBox(D3DXVECTOR3(-10000.0f, -10000.0f, -10000.0f),
- D3DXVECTOR3(10000.0f, 10000.0f, 10000.0f));
- D3DXMATRIX World = GetWorldMatrix();
-
- //Lock vertex buffer of the object
- ObjectVertex* vertexBuffer = NULL;
- m_pMesh->m_pMesh->LockVertexBuffer(0,(void**)&vertexBuffer);
-
- //For each vertex in the mesh
- for(int i=0;i<m_pMesh->m_pMesh->GetNumVertices();i++)
- {
- //Transform vertex to world space using the MESHINSTANCE
- //world matrix, i.e. the position, rotation and scale
- D3DXVECTOR3 pos;
- D3DXVec3TransformCoord(&pos, &vertexBuffer[i]._pos, &World);
-
- // Check if the vertex is outside the bounds
- // if so, then update the bounding volume
- if(pos.x < bBox.min.x)bBox.min.x = pos.x;
- if(pos.x > bBox.max.x)bBox.max.x = pos.x;
- if(pos.y < bBox.min.y)bBox.min.y = pos.y;
- if(pos.y > bBox.max.y)bBox.max.y = pos.y;
- if(pos.z < bBox.min.z)bBox.min.z = pos.z;
- if(pos.z > bBox.max.z)bBox.max.z = pos.z;
- }
-
- m_pMesh->m_pMesh->UnlockVertexBuffer();
-
- return bBox;
- }
-
- BSPHERE MESHINSTANCE::GetBoundingSphere()
- {
- if(m_pMesh == NULL || m_pMesh->m_pMesh == NULL)return BSPHERE();
- if(m_pMesh->m_pMesh->GetFVF() != ObjectVertex::FVF) // XYZ and NORMAL and UV
- return BSPHERE();
-
- BBOX bBox = GetBoundingBox();
- BSPHERE bSphere;
- D3DXMATRIX World = GetWorldMatrix();
- bSphere.center = (bBox.max + bBox.min) / 2.0f;
-
- ObjectVertex* vertexBuffer = NULL;
- m_pMesh->m_pMesh->LockVertexBuffer(0,(void**)&vertexBuffer);
-
- //Get radius
- for(int i=0;i<m_pMesh->m_pMesh->GetNumVertices();i++)
- {
- D3DXVECTOR3 pos;
- D3DXVec3TransformCoord(&pos, &vertexBuffer[i]._pos, &World);
-
- float l = D3DXVec3Length(&(pos - bSphere.center));
- if(l > bSphere.radius)
- bSphere.radius = l;
- }
-
- m_pMesh->m_pMesh->UnlockVertexBuffer();
-
- return bSphere;
- }